#include "EchoServer.h"
#include "TcpConnection.h"

#include "KeyRecommander.h"
#include "WebPageSearcher.h"
#include <functional>
#include <iostream>
#include <sstream>

using std::bind;
using std::cout;
using std::endl;
using std::istringstream;

typedef struct tmp_msg {
    string method;
    string order;
    string param;
} tmp_msg_t;

string urlDecode(const std::string &encoded);
tmp_msg_t analyzeRequest(const string &message);

MyTask::MyTask(const string &msg, const TcpConnectionPtr &con)
    : _msg(msg), _con(con) {
}

void MyTask::process() {
    // 任务处理逻辑，在此处，已经将任务放入了线程池的任务队列中。
    // _con->sendInLoop(_msg);

    // 分解
    // 如果 'param' 为空，直接返回，不做任何处理，结束本次连接
    tmp_msg_t msg_total = analyzeRequest(_msg);
    if (msg_total.param.empty()) {
        cout << "Query parameter 'param' is empty, closing connection." << endl;
        return;
    }

    string pro_arg = urlDecode(msg_total.param); // 转码
    // cout << "调试>>>>信息结构体为：" << msg_total.method << " "
    //      << msg_total.order << " "
    //      << msg_total.param << "\n";

    if (msg_total.order != "s") {
        // 任务一：关键字推荐
        // 调试代码：
        cout << "keyword code is : \n";
        cout << "original query = " << msg_total.param << "\n";
        cout << "processed query = " << pro_arg << "\n";

        // 启动字典
        Dictionary *dic = Dictionary::getInstance();
        dic->init("/home/kyle/Project/WebDisk/data");
        KeyRecommander keyRec(pro_arg, _con, dic);
        keyRec.execute();
    } else {
        // 任务二：网页推荐
        // 调试代码：
        cout << "web code is : \n";
        cout << "original query = " << msg_total.param << "\n";
        cout << "processed query = " << pro_arg << "\n";
        WebPageSearcher wsc(pro_arg, _con);
        wsc.start();
    }
}

EchoServer::EchoServer(size_t threadNum, size_t queSize, const string &ip, unsigned short port)
    : _pool(threadNum, queSize), _server(ip, port) {
}

EchoServer::~EchoServer() {
}

// 服务器的启动与停止
void EchoServer::start() {
    _pool.start();

    // 三个回调放在此处进行注册
    using namespace std::placeholders;
    _server.setAllCallback(bind(&EchoServer::onNewConnection, this, _1), bind(&EchoServer::onMessage, this, _1), bind(&EchoServer::onClose, this, _1));
    _server.start();
}

void EchoServer::stop() {
    _pool.stop();
    _server.stop();
}

// 三个回调
void EchoServer::onNewConnection(const TcpConnectionPtr &con) {
    cout << con->toString() << " has connected!!!" << endl;
}

void EchoServer::onMessage(const TcpConnectionPtr &con) {
    // string msg = con->receive();
    // cout << ">>recv msg from client : " << msg << endl;

    string completeMessage;
    string part;

    // 接收请求，直到读取完完整的HTTP请求
    while (true) {
        part = con->receive();
        completeMessage += part;

        // 检查是否收到完整的HTTP请求（即包含 \r\n\r\n）
        if (completeMessage.find("\r\n\r\n") != string::npos) {
            break;
        }
    }

    // 调试：输出接收到的完整消息
    // cout << ">> Received complete HTTP request:\n"
    //      << completeMessage << endl;

    // 思路一：将HTTP请求体放入任务队列中
    MyTask task(completeMessage, con);
    _pool.addTask(bind(&MyTask::process, task));

    // 思路二：在此处分割http请求信息，根据请求任务不同，传入不同参数，和路径。交由MyTask类处理.
}

void EchoServer::onClose(const TcpConnectionPtr &con) {
    cout << con->toString() << " has closed!!!" << endl;
}

////////////////////////////////////////////////////////////////
///////                 解析参数用到的函数                  //////
////////////////////////////////////////////////////////////////
std::string urlDecode(const std::string &encoded) {
    // 解析中文和英文参数
    std::ostringstream decoded;
    for (std::size_t i = 0; i < encoded.length(); ++i) {
        if (encoded[i] == '%') {
            if (i + 2 < encoded.length()) {
                int value = 0;
                std::istringstream(encoded.substr(i + 1, 2)) >> std::hex >> value;
                decoded << static_cast<char>(value);
                i += 2;
            } else {
                decoded << encoded[i];
            }
        } else if (encoded[i] == '+') {
            decoded << ' ';
        } else {
            decoded << encoded[i];
        }
    }
    return decoded.str();
}

tmp_msg_t analyzeRequest(const string &message) {
    istringstream iss(message);
    tmp_msg_t tmp;

    string line;
    // 只读取第一行的请求体
    if (getline(iss, line)) {
        // 提取查询方法
        // std::cout << "数据预处理： " << line << "\n";
        stringstream ss(line);
        ss >> tmp.method;

        // 提取查询路径
        string args;
        ss >> args; // /?q=nihao
        tmp.order = args.substr(1, 1);

        // 提取查询字符串
        size_t equal_pos = args.find("=");
        tmp.param = args.substr(equal_pos + 1); // nihao
    }

    return tmp;
}

// // 弃用的查询版本
// void give_up() {
//     // 解析参数
//     istringstream iss(_msg);
//     string line;
//     string arg;
//     if (getline(iss, line)) {
//         // 查找查询字符串的起始位置
//         size_t queryStartPos = line.find('?');

//         if (queryStartPos != string::npos) {
//             // 获取查询字符串部分
//             string queryString = line.substr(queryStartPos + 1); // 去掉 '?' 符号

//             // 查找 "query=" 参数的位置
//             size_t queryPos = queryString.find("query=");

//             if (queryPos != string::npos) {
//                 // 跳过 "query="，获取参数值
//                 queryPos += 6; // "query=" 的长度为 6

//                 // 查找参数值的结束位置（空格或末尾）
//                 size_t endPos = queryString.find(' ', queryPos);

//                 // 如果找到了空格，就截取到空格位置，否则截取到字符串末尾
//                 arg = (endPos != string::npos) ? queryString.substr(queryPos, endPos - queryPos) : queryString.substr(queryPos);

//             } else {
//                 cout << "Query parameter 'query' not found." << endl;
//             }
//         } else {
//             cout << "No query string found." << endl;
//         }
//     }

//     // 处理 arg 为空的情况
//     if (arg.empty()) {
//         cout << "Query parameter 'query' is empty, closing connection." << endl;
//         return; // 如果 'arg' 为空，直接返回，不做任何处理，结束本次连接
//     }
// }